//输入
//5 5
//1 5 3 1 1
//1 5 5 1 5
//1 1 2 2 9
//1 5 1 9 3
//9 1 9 9 3
//一个传送阵, 求左上到右下需要的最小代价,  相邻元素的代价为差值的绝对值, 也可以使用传送阵, 到远端相同的num
// 这个是明显的带权路径, 使用d来求解, 核心是每次遍历, 找最小的值, 探索到新的临接点, 加入到队里

const readline = require("readline");
const rl = readline.createInterface({
    input: process.stdin,
    output: process.stdout
});
let m, n; // m行, n列
let initArr = [];
rl.on("line", (line) => {
    if (m === undefined) {
        [m, n] = line.trim().split(/\s+/).map(Number)
    } else {
        initArr.push(line.trim().split(/\s+/).map(Number))
        if (initArr.length === m) {
            console.log(getResult(m, n, initArr))

            // clear
            m = n = undefined
            initArr.length = 0
        }
    }

})

function getResult(m, n, initArr) {
    //初始化, 方向, 同元素统计,移动阵, 传送阵
    let direction = [
        [-1, 0],
        [1, 0],
        [0, 1],
        [-0, -1]
    ]
    let sameMap = {}
    for (let i = 0; i < m; i++) {
        for (let j = 0; j < n; j++) {
            let num = initArr[i][j]
            if (!sameMap[num]) {
                sameMap[num] = []
            }
            sameMap[num].push([i, j])
        }
    }
    let moveMap = {"0,0": 0}
    let transMap = {}

    // 遍历队列
    let pq = [{x: 0, y: 0, value: 0, trans: false}]
    while (pq.length) {
        let {x, y, value, trans} = pq.shift()
        let key = `${x},${y}`
        if(trans) {
            if(transMap.hasOwnProperty(key) && transMap[key] < value) continue
        } else {
            if(moveMap.hasOwnProperty(key) && moveMap[key] < value) continue
        }

        for (const [addX, addY] of direction) {
            let newX = x + addX
            let newY = y + addY
            if (newX >= 0 && newY >= 0 && newX < m && newY < n) {
                let newValue = value + Math.abs(initArr[x][y] - initArr[newX][newY])
                let newKey = `${newX},${newY}`
                if (trans) { // 用了传送阵
                    if (!transMap.hasOwnProperty(newKey) || newValue < transMap[newKey]) {
                        transMap[newKey] = newValue
                        pq.push({
                            x: newX, y: newY, value: newValue, trans
                        })
                    }
                } else {
                    if (!moveMap.hasOwnProperty(newKey) || newValue < moveMap[newKey]) {
                        moveMap[newKey] = newValue
                        pq.push({
                            x: newX, y: newY, value: newValue, trans
                        })
                    }
                }
            }
        }
        if (!trans) { // 尝试使用传送阵
            let arr = sameMap[initArr[x][y]]
            for (const [farX, farY] of arr) {
                let key = `${farX},${farY}`
                if (!transMap.hasOwnProperty(key) || value < transMap[key]) {
                    transMap[key] = value
                    pq.push({
                        x: farX, y: farY, value: value, trans: true
                    })
                }
            }
        }
        pq.sort((a, b) => a.value - b.value)
    }
    // 获取结果
    let resultKey = `${m - 1},${n - 1}`
    return Math.min(moveMap[resultKey] || Infinity, transMap[resultKey] || Infinity)
}